package com.wlz.curator;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.junit.Test;

import javax.sql.DataSource;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *  curator 客户端
 * @author wlz
 * @date 2022-06-25  10:20 下午
 */
@Slf4j
public class CuratorBaseOperationsClient extends CuratorStantaloneBase{

    /**
     *  递归创建 子节点
     * @throws Exception
     */
    @Test
    public void testCreateWithParent() throws Exception {
        CuratorFramework curatorFramework = getCuratorFramework();

        String pathWithParent = "/node-parent/sub-node-1";

        String s = curatorFramework.create().creatingParentsIfNeeded().forPath(pathWithParent);

        log.info("curator create node: {} successfully ", s);

    }

    /**
     *  protection 模式，防止由于异常，导致僵尸节点
     * @throws Exception
     */
    @Test
    public void testCreate() throws Exception{
        CuratorFramework curatorFramework = getCuratorFramework();

        String forPath = curatorFramework.create()
//                .withProtection() // 创建节点是增加 在节点上拼接唯一id
                .withMode(CreateMode.PERSISTENT).forPath("/curator-node", "some-data".getBytes());
        log.info("curator create node: {} successfully ", forPath);
    }

    @Test
    public void testGetData() throws Exception{
        CuratorFramework curatorFramework = getCuratorFramework();
        byte[] bytes = curatorFramework.getData().forPath("/curator-node");

        log.info("get data form node: {} successfully ", new String(bytes));
    }

    @Test
    public void testSetData() throws Exception{
        CuratorFramework curatorFramework = getCuratorFramework();

        curatorFramework.setData().forPath("/curator-node", "channge!".getBytes());
        byte[] bytes = curatorFramework.getData().forPath("/curator-node");
        log.info("get date form node /curator-node : {} successfully. ", new String(bytes));
    }

    /**
     *  guaranteed:该函数的功能如字面意思一样，主要起到一个保障删除成功的作用，其底层工作 方式是:只要该客户端的会话有效，就会在后台持续发起删除请求，直到该数据节点在 ZooKeeper 服务端被删除。
     *  deletingChildrenIfNeeded:指定了该函数后，系统在删除该数据节点的时候会以递归的方式 直接删除其子节点，以及子节点的子节点。
     * @throws Exception
     */
    @Test
    public void testDelete() throws Exception{
        getCuratorFramework().delete().guaranteed().deletingChildrenIfNeeded().forPath("/node-parent");
        log.info(" delete from node /node-parent successfully ...");
    }

    @Test
    public void testListChildren() throws Exception{
        List<String> strings = getCuratorFramework().getChildren().forPath("/discovery/example");
        strings.forEach(System.out::println);
    }

    /**
     *  异步接口
     * @throws Exception
     */
    @Test
    public void testThreadPool() throws Exception{
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        String zk_node = "/zk_ndoe";

        getCuratorFramework().getData().inBackground((client, event) -> {
           log.info("background: {}", event);
        },executorService).forPath(zk_node);


    }

}
